/**
 * 
 */
package fr.cie.blog.modeldao.services;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import fr.cie.blog.beans.Article;
import fr.cie.blog.beans.Category;
import fr.cie.blog.beans.Comment;
import fr.cie.blog.beans.Country;
import fr.cie.blog.beans.Interest;
import fr.cie.blog.beans.Style;
import fr.cie.blog.beans.User;

/**
 * @author Jee3 Assure la transformation Relation => Object
 */
public class Mapper {

	/**
	 * Log4J the logger.
	 */
	private static final Logger LOG = Logger.getLogger(Mapper.class);

	/**
	 * metadata (introspection du ResultSet).
	 */
	private ResultSetMetaData metadata = null;

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped Article
	 * @throws SQLException
	 *             the mapping Exception
	 */
	public final Article mapperArticle(final ResultSet pResult)
			throws SQLException {

		metadata = pResult.getMetaData();

		// bean(s) à mapper
		final Article article = new Article();
		Comment com = new Comment();

		try {

			if (pResult.getString("article.id") == null) {
				article.setId(0);
			} else {
				article.setId(pResult.getInt("article.id"));
			}

			if (pResult.getString("article.name") == null) {
				article.setName("");
			} else {
				article.setName(pResult.getString("article.name"));
			}

			// TODO : Mapper l'utilisateur propriétaire
			// if (pResult.getString("author") == null) {
			// article.setAuthor(mapperUser(pResult.getString("author"));
			// } else {

			// article.setAuthor(pResult.getInt("author"));
			// }

			if (pResult.getString("article.content") == null) {
				article.setContent("");
			} else {
				article.setContent(pResult.getString("article.content"));
			}

			if (pResult.getString("article.publicationDate") == null) {
				// TODO : gérer l'initialisation par défaut de la date
				article.setPublicationDate(null);
			} else {
				article.setPublicationDate(pResult
						.getDate("article.publicationDate"));
			}

			if (pResult.getString("article.status") == null) {
				article.setPublished(false);
			} else {
				article.setPublished(pResult.getBoolean("article.status"));
			}

			// if (pResult.getString("categoryId") == null) {
			// article.setCategory("");
			// } else {
			// article.setCategory(pResult.getString("categoryId"));
			// }

			if (pResult.getString("comment.articleId") == null) {

				article.setCommentList(null);

			} else {

				final List<Comment> commentList = new ArrayList<Comment>();
				// reposition sur le bof du resultset
				pResult.beforeFirst();

				while (pResult.next()) {

					com = mapperComment(pResult);

					commentList.add(com);
					LOG.info("comment is " + com);

				}

				article.setCommentList(commentList);
			}

		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'un Article dans"
					+ " le Mapper, fonction mapperArticle" + e);
		}

		LOG.trace("article.getname " + article.getName());

		return article;
	}

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped Category
	 */
	public final Category mapperCategory(final ResultSet pResult) {
		LOG.trace("entering in mapperCategory");

		final Category category = new Category();

		try {
			if (pResult.getString("category.id") == null) {
				category.setId(0);
			} else {
				category.setId(pResult.getInt("category.id"));
			}

			if (pResult.getString("category.name") == null) {
				category.setName("");
			} else {
				category.setName(pResult.getString("category.name"));
			}
		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'une "
					+ "Catégorie dans le Mapper, fonction mapperCategory" + e);
		}
		return category;
	}

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped Comment
	 */
	public final Comment mapperComment(final ResultSet pResult) {
		LOG.trace("entering in mapperComment");

		final Comment comment = new Comment();

		try {
			if (pResult.getString("comment.id") == null) {
				comment.setId(0);
			} else {
				comment.setId(pResult.getInt("comment.id"));
			}

			if (pResult.getString("comment.name") == null) {
				comment.setName("");
			} else {
				comment.setName(pResult.getString("comment.name"));
			}

			if (pResult.getString("comment.content") == null) {
				comment.setContent("");
			} else {
				comment.setContent(pResult.getString("comment.content"));
			}

			if (pResult.getString("comment.status") == null) {
				comment.setPublished(false);
			} else {
				comment.setPublished(pResult.getBoolean("comment.status"));
			}

		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'un "
					+ "Commentaire dans le Mapper, fonction mapperComment" + e);
		}
		return comment;
	}

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped Style
	 */
	public final Style mapperStyle(final ResultSet pResult) {

		final Style style = new Style();

		// il peut se poser un problème de type NullPointerException lorsqu'on
		// balance un ordre sql du type SELECT x, y, e From TABLE on peut
		// utiliser un objet ResultSetMetaData pour introspecter le resultset
		// (combien de colonnes, quels sont leur noms ...

		try {
			if (pResult.getString("style.id") == null) {
				style.setId(0);
			} else {
				style.setId(pResult.getInt("style.id"));
			}

			if (pResult.getString("style.name") == null) {
				style.setName("");
			} else {
				style.setName(pResult.getString("style.name"));
			}

			if (pResult.getString("style.status") == null) {
				style.setStatus("");
			} else {
				style.setStatus(pResult.getString("style.status"));
			}
		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'un style dans"
					+ " le Mapper, fonction mapperStyle" + e);
		}

		return style;
	}

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped User
	 */
	public final User mapperUser(final ResultSet pResult) {

		final User user = new User();

		try {
			if (pResult.getString("user.id") == null) {
				user.setId(0);
			} else {
				user.setId(pResult.getInt("user.id"));
			}

			if (pResult.getString("user.name") == null) {
				user.setName("");
			} else {
				user.setName(pResult.getString("user.name"));
			}

			if (pResult.getString("user.role") == null) {
				user.setRole(0);
			} else {
				user.setRole(pResult.getInt("user.role"));
			}
			if (pResult.getString("user.login") == null) {
				user.setLogin("");
			} else {
				user.setLogin(pResult.getString("user.login"));
			}
			if (pResult.getString("user.password") == null) {
				user.setPassword("");
			} else {
				user.setPassword(pResult.getString("user.password"));
			}
			if (pResult.getString("user.surname") == null) {
				user.setSurname("");
			} else {
				user.setSurname(pResult.getString("user.surname"));
			}
			if (pResult.getString("user.email") == null) {
				user.setEmail("");
			} else {
				user.setEmail(pResult.getString("user.email"));
			}
			// TODO : Mapper les articles et commentaires avec l'utilisateur
		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'un Utilisateur"
					+ " dans le Mapper, fonction mapperUser" + e);
		}

		return user;
	}

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped Country
	 */
	public final Country mapperCountry(final ResultSet pResult) {
		final Country country = new Country();

		try {
			if (pResult.getString("country.id") == null) {
				country.setId(0);
			} else {
				country.setId(pResult.getInt("country.id"));
			}

			if (pResult.getString("country.name") == null) {
				country.setName("");
			} else {
				country.setName(pResult.getString("country.name"));
			}

			if (pResult.getString("country.countryCode") == null) {
				country.setCountryCode("");
			} else {
				country.setCountryCode(
						pResult.getString("country.countryCode"));
			}

			// TODO : Mapper les pays avec les card
		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'un pays dans"
					+ " le Mapper, fonction mapperCountry" + e);
		}

		return country;
	}

	/**
	 * @param pResult
	 *            the reference ResultSet
	 * @return the mapped Interest
	 */
	public final Interest mapperInterest(
			final ResultSet pResult) {
		final Interest interest = new Interest();
		
		try {
			if (pResult.getString("interest.id") == null) {
				interest.setId(0);
			} else {
				interest.setId(pResult.getInt("interest.id"));
			}

			if (pResult.getString("interest.name") == null) {
				interest.setName("");
			} else {
				interest.setName(pResult.getString("interest.name"));
			}
			// TODO : Mapper les loisirs avec les cards
		} catch (final Exception e) {
			// Si il y a une erreur durant le mapping des attributs
			LOG.debug("Erreur lors du mapping des attributs d'un Loisir dans"
					+ " le Mapper, fonction mapperInterest" + e);
		}

		return interest;
	}

}
